//
//  GameLayer.m
//  CarDemo
//
//  Created by huang kun on 8/9/10.
//  Copyright 2010 UESTC. All rights reserved.
//

#import "GameLayer.h"
#import "MenuLayer.h"
#import "Constant.h"
#import "ShopLayer.h"

typedef enum {
	kzorderBg,
	kzorderBg2,
	kzorderMenu,
	kzorderMenuItmes,
	kzorderBlock,
	kzorderCar,
	kzorderCurrentBlock,
	kzorderSpade,
	kzorderGold,
	kzorderShop,
	kzorderBack,

} GameLayerZorders;


typedef enum  {
	ktagTimePointer = 100,
	ktagGoldLabel,
	ktagShop,
	ktagWin,
	ktagBack,
	ktagGoldSheet,
	ktagCarSheet,
} GameLayerTags;


@interface GameLayer(Private)

- (void) lose;
- (void) win;
- (void) addGold;
@end


@implementation GameLayer

@synthesize gold;


- (void) dealloc {
	[map release];
	[self removeAllChildrenWithCleanup:YES];
	[super dealloc];
}

- (void) setGold:(int)g {
	if(g >= 0) {
		gold = g;
		CCLabel *goldLabel = (CCLabel *)[self getChildByTag:ktagGoldLabel];
		[goldLabel setString:[NSString stringWithFormat:@"%d",gold]];
	}
}

- (id) init {
	if( (self = [super init]) ){
		isTouchEnabled = YES;
		CGSize winSize = [[CCDirector sharedDirector] winSize];
		
		
		CCSprite *bg = [CCSprite spriteWithFile:@"gameBg1.png"];
		[self addChild:bg z:kzorderBg];
		[bg setPosition:ccp(bg.contentSize.width/2, winSize.height/2)];
		
#define bgMoveSpeed 50.0f
		
		float dis = bg.contentSize.width - winSize.width;
		id move1 = [CCMoveBy actionWithDuration:dis/bgMoveSpeed position:ccp(-dis, 0)];
		dis = (bg.contentSize.width - winSize.width) /2;
		id move2 = [CCMoveBy actionWithDuration:dis/bgMoveSpeed position:ccp(dis, 0)];
		id callFunc = [CCCallFunc actionWithTarget:self selector:@selector(load:)];
		[bg runAction:[CCSequence actions:move1, move2, callFunc, nil]];
		
		
		map = [[Map alloc] init];
	}
	return self;
}

- (void) addGold {
	CGSize winSize = [[CCDirector sharedDirector] winSize];
	
#define fallSpeed 300.0f
	
	//CCSpriteSheet *sheet = [CCSpriteSheet spriteSheetWithFile:@"golds.png"];
	//[self addChild:sheet z:kzorderGold tag:ktagGoldSheet];
	CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:@"golds.png"];
	
	CCAnimation *animation = [CCAnimation animationWithName:nil delay:0.1f];
	for (int i=1;i<11;i++)
		[animation addFrameWithTexture:texture rect:CGRectMake(35*i, 0, 35, 35)];
	
	
	CCSprite *gold1 = [CCSprite spriteWithTexture:texture rect:CGRectMake(0, 0, 35, 35)];
	[self addChild:gold1 z:kzorderGold];
	[gold1 setPosition:ccp(99, winSize.height + gold1.contentSize.height/2)];
	[gold1 runAction:[CCRepeatForever actionWithAction:
					  [CCAnimate actionWithAnimation:animation restoreOriginalFrame:YES]]];
	[gold1 runAction:[CCMoveBy actionWithDuration:(gold1.position.y-228)/fallSpeed position:ccp(0, -(gold1.position.y-228))]];
	
	CCSprite *gold2 = [CCSprite spriteWithTexture:texture rect:CGRectMake(0, 0, 35, 35)];
	[self addChild:gold2 z:kzorderGold];
	[gold2 setPosition:ccp(99, winSize.height + gold2.contentSize.height/2)];
	
	[gold2 runAction:[CCRepeatForever actionWithAction:
					  [CCAnimate actionWithAnimation:animation restoreOriginalFrame:YES]]];

	[gold2 runAction:[CCMoveBy actionWithDuration:(gold2.position.y-71)/fallSpeed position:ccp(0, -(gold2.position.y-71))]];
	
	
	
	CCSprite *gold3 = [CCSprite spriteWithTexture:texture rect:CGRectMake(0, 0, 35, 35)];
	[self addChild:gold3 z:kzorderGold];
	[gold3 setPosition:ccp(408, winSize.height + gold3.contentSize.height/2)];
	[gold3 runAction:[CCRepeatForever actionWithAction:
					  [CCAnimate actionWithAnimation:animation restoreOriginalFrame:YES]]];

	
	[gold3 runAction:[CCMoveBy actionWithDuration:(gold3.position.y-228)/fallSpeed position:ccp(0, -(gold3.position.y-228))]];
	
	
	
	CCSprite *gold4 = [CCSprite spriteWithTexture:texture rect:CGRectMake(0, 0, 35, 35)];
	[self addChild:gold4 z:kzorderGold];
	[gold4 setPosition:ccp(408, winSize.height + gold4.contentSize.height/2)];
	[gold4 runAction:[CCRepeatForever actionWithAction:
					  [CCAnimate actionWithAnimation:animation restoreOriginalFrame:YES]]];

	[gold4 runAction:[CCMoveBy actionWithDuration:(gold4.position.y-71)/fallSpeed position:ccp(0, -(gold4.position.y-71))]];
	
}

- (void) load:(id)sender {
	CGSize winSize = [[CCDirector sharedDirector] winSize];
	
	CCSprite *bg = [CCSprite spriteWithFile:@"gameBg2.png"];
	[self addChild:bg z:kzorderBg2];
	[bg setPosition:ccp(bg.contentSize.width/2, winSize.height/2)];
	
	[self loadBlock];
	
	CCLabel *goldLabel = [CCLabel labelWithString:@"0" fontName:@"Arial" fontSize:17];
	[self addChild:goldLabel z:kzorderMenuItmes tag:ktagGoldLabel];
	[goldLabel setPosition:ccp(129, 301)];
	[self setGold:0];
	
	//仪表指针
	CCSprite *pointer = [CCSprite spriteWithFile:@"pointer.png"];
	[self addChild:pointer z:kzorderMenuItmes tag:ktagTimePointer];
	[pointer setAnchorPoint:ccp(0.5, 0)];
	[pointer setPosition:ccp(29, 281)];
	[pointer setRotation:100];
	maxTime = 600;
	time = maxTime;
	
	[self schedule:@selector(count:) interval:1.0f];
	
	//黑盖
	CCSprite *pointerCover = [CCSprite spriteWithFile:@"pointerCover.png"];
	[self addChild:pointerCover z:kzorderMenuItmes];
	[pointerCover setPosition:ccp(29, 275)];
	
	//当前块
	//currBlock = [CCSprite spriteWithFile:@"bigBlock1.png"];
	currBlock = [CurrentBlock node];
	[currBlock setType:kblockType2];
	[self addChild:currBlock z:kzorderCurrentBlock];
	[currBlock setPosition:ccp(29, 222)];
	[currBlock setDelegate:self];
	[currBlock setBlockNum:50];
	//下一块
	//nextBlock = [CCSprite spriteWithFile:@"bigBlock2.png"];
	/*	nextBlock = [NextBlock node];
	 [nextBlock setType:kblockType1];
	 [self addChild:nextBlock z:kzorderMenuItmes];
	 [nextBlock setPosition:ccp(32, 160)];
	 */
	//下一块
	spade = [Spade node];// spriteWithFile:@"spade.png"];
	[spade setDelegate:self];
	[self addChild:spade z:kzorderSpade];
	[spade setPosition:ccp(199, 303)];
	
	//工具箱
	CCMenuItemImage *toolBox = [CCMenuItemImage itemFromNormalImage:@"toolBox.png" selectedImage:@"toolBox.png"
															 target:self selector:@selector(didSelectToolBox:)];
	CCMenuItemImage *menuButton = [CCMenuItemImage itemFromNormalImage:@"menu.png" selectedImage:@"menu02.png"
																target:self selector:@selector(backToMenu:)];
	
	CCMenu *menu = [CCMenu menuWithItems:toolBox,menuButton,nil];
	[self addChild:menu z:kzorderMenuItmes];
	[menu setPosition:CGPointZero];
	[toolBox setPosition:ccp(31, 101)];
	[menuButton setPosition:ccp(434, 304)];
	
	CCLabel *level = [CCLabel labelWithString:@"LEVEL 1-1" fontName:@"Arial" fontSize:17];
	[self addChild:level z:kzorderMenuItmes];
	[level setPosition:ccp(422, 9)];
	[level setColor:ccYELLOW];
}

- (void) count:(ccTime) interval {
	time--;
	if(time <= 0){
		[self lose];
	}
	else {
		CCSprite *pointer = (CCSprite *)[self getChildByTag:ktagTimePointer];
		[pointer setRotation:pointer.rotation-200.0f/maxTime];
	}
}


- (void) lose {
}

- (void) check {
	BOOL b = [map testMap];
	if(b) {
		NSLog(@"success");
		[currBlock setAvaliable:NO];
		
		car = [CCSprite spriteWithFile:@"car1.png"];
		[self addChild:car z:kzorderCar];
		[car setPosition:ccp(94,266)];
		
		CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:@"gas.png"];
		
		CCAnimation *animation = [CCAnimation animationWithName:nil delay:1.0f/24];
		for (int i=1;i<8;i++)
			[animation addFrameWithTexture:texture rect:CGRectMake(38*i, 0, 38, 38)];
		CCSprite *gas = [CCSprite spriteWithTexture:texture rect:CGRectMake(0, 0, 38, 38)];
		[car addChild:gas];
		[gas setPosition:ccp(0, -20)];
		[gas runAction:[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:animation restoreOriginalFrame:YES]]];
		
		
		for (int i=0;i<63;i++){
			Block *block = (Block *)[self getChildByTag:i];
			if(block)
				[block setIsTouchEnable:NO];
		}
		
		NSMutableArray *array = [NSMutableArray arrayWithCapacity:map.path.top];
		for (int i=0;i< map.path.top;i++){
			int Tag = map.path.data[i].x+map.path.data[i].y * roadRow;
			NSLog(@"%d,%d,%d", map.path.data[i].x,map.path.data[i].y,Tag);
			Block *block = (Block *)[self getChildByTag:Tag];
			if(block){
				[block setConnect:YES];
			}
			CGPoint p;
			id rotateTo;

			switch (map.path.data[i].direction) {
				case UP:
				{
					p = ccp(0, 38);
					rotateTo = [CCRotateTo actionWithDuration:0.2 angle:0];
				}
					break;
				case DOWN:
				{
					p = ccp(0, -38);
					rotateTo = [CCRotateTo actionWithDuration:0.2 angle:180];
				}
					break;
				case LEFT:
				{
					p = ccp(-38, 0);
					rotateTo = [CCRotateTo actionWithDuration:0.2 angle:-90];
				}
					break;
				case RIGHT:
				{
					p = ccp(38, 0);
					rotateTo = [CCRotateTo actionWithDuration:0.2 angle:90];
				}
					break;
				default:
					break;
			}
			id moveBy = [CCMoveBy actionWithDuration:0.5f position:p];
			if (i > 0 && map.path.data[i-1].direction == map.path.data[i].direction);
			else [array addObject:rotateTo];
			[array addObject:moveBy];
		}
		id callFunc = [CCCallFunc actionWithTarget:self selector:@selector(win:)];
		[array addObject:callFunc];
		[car runAction:[CCSequence actionWithArray:array]];
		[array removeAllObjects];
	}
}

- (void) win:(id)sender {
	NSLog(@"win");
	CCSprite *win = [CCSprite spriteWithFile:@"win.png"];
	[self addChild:win z:kzorderShop tag:ktagWin];
	[win setPosition:ccp(240, 160)];
}

- (void) didSelectToolBox:(id)sender {
	if( [self getChildByTag:ktagShop] == nil){
		ShopLayer *shop = [ShopLayer node];
		[self addChild:shop z:kzorderShop tag:ktagShop];
	}
}


- (BOOL) shouldPlantAtPosition:(CGPoint)position {
	CGRect rect = roadRect;
	if(CGRectContainsPoint(rect, position)){
		//减去偏移量
		position = [self convertToGridPosition:position];
		position = ccpSub(position, rect.origin);
		//行
		int y = (int)position.y / (int)roadHeight;
		//列
		int x = (int)position.x / (int)roadWidth;
		
		return [map shouldSet:x y:y];
	}
	return NO;
}




- (void) loadBlock {
	//障碍物
	CGSize winSize = [[CCDirector sharedDirector] winSize];
	
//#define fallSpeed 300.0f
	
	[self addGold];
	/*CCSprite *gold1 = [CCSprite spriteWithFile:@"gold.png"];
	[self addChild:gold1 z:kzorderGold];
	[gold1 setPosition:ccp(99, winSize.height + gold1.contentSize.height/2)];
	[gold1 runAction:[CCMoveBy actionWithDuration:(gold1.position.y-228)/fallSpeed position:ccp(0, -(gold1.position.y-228))]];

	CCSprite *gold2 = [CCSprite spriteWithFile:@"gold.png"];
	[self addChild:gold2 z:kzorderGold];
	[gold2 setPosition:ccp(99, winSize.height + gold2.contentSize.height/2)];
	[gold2 runAction:[CCMoveBy actionWithDuration:(gold2.position.y-71)/fallSpeed position:ccp(0, -(gold2.position.y-71))]];

	CCSprite *gold3 = [CCSprite spriteWithFile:@"gold.png"];
	[self addChild:gold3 z:kzorderGold];
	[gold3 setPosition:ccp(408, winSize.height + gold3.contentSize.height/2)];
	[gold3 runAction:[CCMoveBy actionWithDuration:(gold3.position.y-228)/fallSpeed position:ccp(0, -(gold3.position.y-228))]];

	
	CCSprite *gold4 = [CCSprite spriteWithFile:@"gold.png"];
	[self addChild:gold4 z:kzorderGold];
	[gold4 setPosition:ccp(408, winSize.height + gold4.contentSize.height/2)];
	[gold4 runAction:[CCMoveBy actionWithDuration:(gold4.position.y-71)/fallSpeed position:ccp(0, -(gold4.position.y-71))]];
	*/
	CCSprite *block = [CCSprite spriteWithFile:@"mountain.png"];
	[self addChild:block z:kzorderBlock];
	[block setPosition:ccp(253, winSize.height + block.contentSize.height/2)];
	[block runAction:[CCMoveBy actionWithDuration:(block.position.y-149)/fallSpeed position:ccp(0, -(block.position.y-149))]];
	
}

- (void) backToMenu:(id)sender {
	if( [self getChildByTag:ktagBack] == nil) {
		CCSprite *menu = [CCSprite spriteWithFile:@"backToMenu.png"];
		[self addChild:menu z:kzorderBack tag:ktagBack];
		[menu setPosition:ccp(240, 160)];
		
		CCMenuItemImage *back = [CCMenuItemImage itemFromNormalImage:@"menu001.png" selectedImage:@"menu003.png"
															  target:self selector:@selector(back:)];
		
		CCMenuItemImage *notBack = [CCMenuItemImage itemFromNormalImage:@"return01.png" selectedImage:@"return03.png"
																 target:self selector:@selector(continueGame:)];
		
		CCMenu *menu2 = [CCMenu menuWithItems:back,notBack,nil];
		[menu addChild:menu2];
		[menu2 setPosition:CGPointZero];
		[back setPosition:ccp(315, 165)];
		[notBack setPosition:ccp(183, 165)];

	}
}
- (void) back:(id)sender {	
	[[CCTextureCache sharedTextureCache] removeUnusedTextures];
	[[CCTextureCache sharedTextureCache] removeAllTextures];
	[[CCDirector sharedDirector] replaceScene:[[CCScene node] addChild:[MenuLayer node]]];
}

- (void) continueGame:(id)sender {
	CCSprite *back = (CCSprite *)[self getChildByTag:ktagBack];
	[back removeAllChildrenWithCleanup:YES];
	[self removeChildByTag:ktagBack cleanup:YES];
}

- (CGPoint) convertToGridPosition:(CGPoint)position{
	CGRect rect = roadRect;
	if(CGRectContainsPoint(rect, position)){
		//减去偏移量
		position = ccpSub(position, rect.origin);
		//行
		int column = (int)position.y / (int)roadHeight;
		//列
		int row = (int)position.x / (int)roadWidth;
		//网格中心
		CGPoint cp = ccp(roadWidth * (row+0.5), roadHeight * (column+0.5));
		
		//加上偏移量
		//NSLog(@"%@",NSStringFromCGPoint(cp));
		return ccpAdd(rect.origin, cp);
	}
	return CGPointZero;
}

- (BOOL) addBlock:(Block *)block position:(CGPoint) p {
	p = [self convertToGridPosition:p];
	if( !CGPointEqualToPoint(p, CGPointZero)){
		
			CGPoint p2 = ccpSub(p, roadRect.origin);
			//行
			int y = (int)p2.y / (int)roadHeight;
			//列
			int x = (int)p2.x / (int)roadWidth;
		
		if([map shouldSet:x y:y]){
			[self addChild:block  z:kzorderBlock];
			[block setPosition:p];
			[block setDelegate:self];
			[block setTag:x+y*roadRow];
			[block setIsTouchEnable:YES];
			[map updateMapArray:x y:y block:[block getBlock]];
			
			[self check];
			return YES;
		}
	}
	return NO;
}


- (BOOL) removePlantByPosition:(CGPoint)p {
	p = [self convertToGridPosition:p];
	if( !CGPointEqualToPoint(p, CGPointZero)){		
		p = ccpSub(p, roadRect.origin);
		//行
		int y = (int)p.y / (int)roadHeight;
		//列
		int x = (int)p.x / (int)roadWidth;
		
		Block *block = (Block *)[self getChildByTag:x+y*roadRow];
		if(block) {
			[self removeChildByTag:x+y*roadRow cleanup:YES];
			BlockShape shape = {kblocked, kblocked, kblocked, NO};
			[map updateMapArray:x y:y block:shape];
			return YES;
		}
	}
	return NO;
}

- (void) updateBlock:(Block *)block {
    CGPoint	p = block.position; 
	p = [self convertToGridPosition:p];
	p = ccpSub(p, roadRect.origin);
	//行
	int y = (int)p.y / (int)roadHeight;
	//列
	int x = (int)p.x / (int)roadWidth;
	
	[map updateMapArray:x y:y block:[block getBlock]];
	
	[self check];
}

@end
